import TileModel;
import VectorModel;

import flash.geom.Point;

class TileCollisionController
{
  
  public function new()
  {
  }


  public function squareModelCollision
	(
	  gameObject:SquareModel, 
	  gameObject2:SquareModel
	):Bool
   { 
      var collided = false;			
      //Vector between rectangles
      var squareVector = new VectorModel();
      squareVector.update(gameObject.xPos+gameObject.width * 0.5 , gameObject.yPos+gameObject.height * 0.5 ,
	    gameObject2.xPos+gameObject2.width * 0.5 , gameObject2.yPos+gameObject2.height * 0.5 ); 
      if(Math.abs(squareVector.vx) < gameObject.width * 0.5 + gameObject2.width * 0.5)
      {
	
	if(Math.abs(squareVector.vy) < gameObject.height * 0.5 + gameObject2.height * 0.5)
	{    
//       if(squareVector.vx > -gameObject2.width && squareVector.vx <= 0 ||
// 	 squareVector.vx < gameObject.width && squareVector.vx >= 0)
//       {
// 	if(squareVector.vy > -gameObject2.height && squareVector.vy <= 0 ||
// 	 squareVector.vy < gameObject.height && squareVector.vy >= 0)
// 	{
	  //A collision has ocurred.
	  collided = true;
	}
      }
      return collided;
	  
   } 
  public function shotPlatformCollision
	(
	  shotVector:VectorModel, 
	  _platformMap:Array<Array<Int>>, 
	  PLATFORM:Int,
	  MAX_TILE_SIZE:Int,
	  MAP_COLUMNS:Int,
	  MAP_ROWS:Int
	)
   { 

      var remainder = shotVector.a.x% MAX_TILE_SIZE;
      if(shotVector.vx > 0)
      {     
      var xToCheck = MAX_TILE_SIZE-remainder;
      var vxRemain = shotVector.vx;
      while(xToCheck <= vxRemain)
	{
	  var newX = ((xToCheck)+shotVector.a.x);
	  var newY = (shotVector.slope*(newX)+shotVector.y_intercept);
	  var TileX = Math.floor(newX/MAX_TILE_SIZE);
	  if(TileX < 0 || TileX > MAP_COLUMNS-1)
	    {break;}
	  var TileY = Math.floor(newY/MAX_TILE_SIZE);
	  if(TileY < 0 || TileY > MAP_ROWS-1)
	    {break;}
	  if(_platformMap[TileY][TileX] == PLATFORM)
	    {shotVector.update(shotVector.a.x,shotVector.a.y,newX,newY); break;}
	  xToCheck = xToCheck+MAX_TILE_SIZE;
	}
      }
      else
      {
      var xToCheck = remainder;
      var vxRemain = shotVector.vx;
      while(-xToCheck >= vxRemain)
	{
	var newX = (shotVector.a.x-(xToCheck));
	var newY = (shotVector.slope*(newX)+shotVector.y_intercept);
	  var TileX = Math.floor(newX/MAX_TILE_SIZE)-1;
	  if(TileX < 0 || TileX > MAP_COLUMNS-1)
	    {break;}
	  var TileY = Math.floor(newY/MAX_TILE_SIZE);
	  if(TileY < 0 || TileY > MAP_ROWS-1)
	    {break;}
	if(_platformMap[TileY][TileX] == PLATFORM)
	  {shotVector.update(shotVector.a.x,shotVector.a.y,newX,newY); break;}
	xToCheck = xToCheck+MAX_TILE_SIZE;
	}
      }

      var remainder = shotVector.a.y%MAX_TILE_SIZE;
      if(shotVector.vy > 0)
      {     
      var yToCheck = MAX_TILE_SIZE-remainder;
      var vyRemain = shotVector.vy;
      while(yToCheck <= vyRemain)
	{
	var newY = ((yToCheck)+shotVector.a.y);
	var newX = ((newY-shotVector.y_intercept)/shotVector.slope);
	  var TileX = Math.floor(newX/MAX_TILE_SIZE);
	  if(TileX < 0 || TileX > MAP_COLUMNS-1)
	    {break;}
	  var TileY = Math.floor(newY/MAX_TILE_SIZE);
	  if(TileY < 0 || TileY > MAP_ROWS-1)
	    {break;}
	if(_platformMap[TileY][TileX] == PLATFORM)
	  {shotVector.update(shotVector.a.x,shotVector.a.y,newX,newY); break;}
	yToCheck = yToCheck+MAX_TILE_SIZE;
	}
      }
      else
      {
      var yToCheck = remainder;
      var vyRemain = shotVector.vy;
      while(-yToCheck >= vyRemain)
	{
	var newY = (shotVector.a.y-(yToCheck));
	var newX = ((newY-shotVector.y_intercept)/shotVector.slope);
	  var TileX = Math.floor(newX/MAX_TILE_SIZE);
	  if(TileX < 0 || TileX > MAP_COLUMNS-1)
	    {break;}
	  var TileY = Math.floor(newY/MAX_TILE_SIZE)-1;
	  if(TileY < 0 || TileY > MAP_ROWS-1)
	    {break;}
	if(_platformMap[TileY][TileX] == PLATFORM)
	  {shotVector.update(shotVector.a.x,shotVector.a.y,newX,newY); break;}
	yToCheck = yToCheck+MAX_TILE_SIZE;
	}
      }
   }

  public function shotSquareCollision
    (
      shotVector:VectorModel, 
      square:TileModel
    ):Bool
  {
    var hit = false;
  
    //Check each side
  //check left
   if(shotVector.a.x <= square.xPos && shotVector.b.x >= square.xPos)
      {
	var y = shotVector.slope*(square.xPos)+shotVector.y_intercept;
	if(y >= square.yPos && y<= square.yPos+square.height)
	{
	  hit = true;
	}
      }
    //check right
    if(shotVector.a.x >= square.xPos+square.width && shotVector.b.x <= square.xPos+square.width)
      {
	var y = shotVector.slope*(square.xPos+square.width)+shotVector.y_intercept;
	if(y >= square.yPos && y<= square.yPos+square.height)
	{
	  hit = true;
	}
      }
    //check top
     if(shotVector.a.y <= square.yPos && shotVector.b.y >= square.yPos)
      {
	var x = (square.yPos-shotVector.y_intercept)/shotVector.slope;
	if(x >= square.xPos && x <= square.xPos+square.width)
	{
	  hit = true;
	}
      }
      //check Bottom
     if(shotVector.a.y <= square.yPos+square.height && shotVector.b.y >= square.yPos+square.height)
      {
	var x = (square.yPos-shotVector.y_intercept)/shotVector.slope;
	if(x >= square.xPos && x <= square.xPos+square.width)
	{
	  hit = true;
	}
      }
    
    return hit;
  }


  public function shotCircleCollisionSide
    (
      shotVector:VectorModel, 
      circleX:Float, 
      circleY:Float,
      tileRadius:Float
    ):String
  {
    


      var _lineSide = "";
      var rightPoint:VectorModel = new VectorModel();
      var leftPoint:VectorModel = new VectorModel();
      var _v3:VectorModel = new VectorModel();

      rightPoint.update
	      (
		circleX, 
		circleY, 
		shotVector.b.x,
		shotVector.b.y
		);       
      leftPoint.update
	    (
		circleX, 
		circleY, 
		shotVector.a.x,
		shotVector.a.y
	    );  
    _v3.update(circleX, circleY, shotVector.a.x, shotVector.a.y); 
    //The dot product that tells you whether the circle is within
    //the scope of the line's magnitude
    var dp1:Float = VectorMath.dotProduct(_v3, shotVector);
    
    //The dotproduct that tells you which side of the line
    //the circle is on
    var dp2:Float = VectorMath.dotProduct(_v3, shotVector.ln);
   // trace(dp2 < tileRadius && dp2 > -tileRadius); 
    //If the circle is within the scope of the line's magnitude
    //then set its line side to left or right
    if(dp1 > -shotVector.m && dp1 < 0 )
    {
      if(_lineSide == "")
      {
	if(dp2 < 0 )
	{
	  _lineSide = "left";
	}   
	else
	{
	  _lineSide = "right";
	}
      }
    }
    else
    {
      //If the circle is not within the line's 
      //scope (such as rounding
      //a corner) clear the _lineSide variable.
      _lineSide = "";
    }

    //Create an environmental boundary based on whether
    //the circle has collided from the right or left
    if(dp2 >  -tileRadius && _lineSide == "left"
    || dp2 <  tileRadius && _lineSide == "right" ||
    rightPoint.m < tileRadius || leftPoint.m < tileRadius
    )
    { 
      return _lineSide;
    }
    return "";
  }
  public function shotCircleCollision
    (
      shotVector:VectorModel, 
      circleX:Float, 
      circleY:Float,
      tileRadius:Float
    ):Bool
  {
    


      var _lineSide = "";
      var rightPoint:VectorModel = new VectorModel();
      var leftPoint:VectorModel = new VectorModel();
      var _v3:VectorModel = new VectorModel();

      rightPoint.update
	      (
		circleX, 
		circleY, 
		shotVector.b.x,
		shotVector.b.y
		);       
      leftPoint.update
	    (
		circleX, 
		circleY, 
		shotVector.a.x,
		shotVector.a.y
	    );  
    _v3.update(circleX, circleY, shotVector.a.x, shotVector.a.y); 
    //The dot product that tells you whether the circle is within
    //the scope of the line's magnitude
    var dp1:Float = VectorMath.dotProduct(_v3, shotVector);
    
    //The dotproduct that tells you which side of the line
    //the circle is on
    var dp2:Float = VectorMath.dotProduct(_v3, shotVector.ln);
   // trace(dp2 < tileRadius && dp2 > -tileRadius); 
    //If the circle is within the scope of the line's magnitude
    //then set its line side to left or right
    if(dp1 > -shotVector.m && dp1 < 0 )
    {
      if(_lineSide == "")
      {
	if(dp2 < 0 )
	{
	  _lineSide = "left";
	}   
	else
	{
	  _lineSide = "right";
	}
      }
    }
    else
    {
      //If the circle is not within the line's 
      //scope (such as rounding
      //a corner) clear the _lineSide variable.
      _lineSide = "";
    }

    //Create an environmental boundary based on whether
    //the circle has collided from the right or left
    if(dp2 >  -tileRadius && _lineSide == "left"
    || dp2 <  tileRadius && _lineSide == "right" ||
    rightPoint.m < tileRadius || leftPoint.m < tileRadius
    )
    {  
      trace(_lineSide);
      return true;

    }
    return false;
  }

  public function squareCollision
	(
	  gameObject:TileModel, 
	  gameObject2:TileModel
	):Bool
   { 
      var collided = false;			
      //Vector between rectangles
      var squareVector = new VectorModel();
      squareVector.update(gameObject.xPos, gameObject.yPos, gameObject2.xPos, gameObject2.yPos); 
      
      //Check whether the projection on the 
      //x axis (in this case the v0's vx) 
      //is less than the combined half widths
      if(squareVector.vx > -gameObject2.width && squareVector.vx <= 0 ||
	 squareVector.vx < gameObject.width && squareVector.vx >= 0)
      {
	//A collision might be occurring! Check the other 
	//projection on the y axis (v0's vy)
	if(squareVector.vy > -gameObject2.height && squareVector.vy <= 0 ||
	 squareVector.vy < gameObject.height && squareVector.vy >= 0)
	{
	  //A collision has ocurred.
	  collided = true;
	}
      }
      return collided;
	  
   } 


  public function platformCollision
	(
	  gameObject:TileModel, 
	  platformMap:Array<Array<Int>>, 
	  maxTileSize:Int,
	  platform:Int,
	  bounceY:Float = 0,
	  bounceX:Float = 0,
	  offsetY:Float = 0,
	  offsetX:Float = 0
	):Point
   { 
      var PlatformHit = new Point(-1,-1);
      if(gameObject.jumping == 0)
	gameObject.jumping = 1;
      //Variables needed to figure out by how much the object
      //is overlapping the tile on the x and y axis
      //The axis with the most overlap is the axis on which
      //the collision is occurring. This is an inverted SAT system
      var overlapX:Float;
      var overlapY:Float;
      //If the object's top left corner is overlapping the tile
      //on its upper left side...
      if(platformMap[gameObject.top][gameObject.left] != Constants.SKY)
      {
        //Figure out by how much the object's top left corner
        //point is overlapping the tile on both the x and y
        //axes. 
	PlatformHit.x = gameObject.left;PlatformHit.y = gameObject.top;
        overlapX = gameObject.xPos % maxTileSize;
        overlapY = gameObject.yPos % maxTileSize;
        if(overlapY >= overlapX)
        {
          if(gameObject.vy < 0
          && platformMap[gameObject.bottom][gameObject.left] 
          != platform)
          {
            //Collision on top side of the object
            //Position the object to the bottom 
            //edge of the platform tile
            //which it is overlapping and set its vy to zero
            gameObject.setY = (gameObject.mapRow * maxTileSize);
	    gameObject.vy = -gameObject.vy * bounceY;
	  }
  
        }
        else
        {
          //Collision on left side of the object
          //Position the object to the right 
          //edge of the platform tile and set its vx to zero
          gameObject.setX 
            = gameObject.mapColumn * maxTileSize;
          if(gameObject.vx < 0){gameObject.vx = -gameObject.vx * bounceX;}
        }
	  gameObject.setY = gameObject.yPos+offsetY;
          gameObject.setX = gameObject.xPos+offsetX;
      }
      
      //If the object's bottom left corner is overlapping the tile
      //on its lower left side...

      if(platformMap[gameObject.bottom][gameObject.left] != Constants.SKY)
      {
      PlatformHit.x = gameObject.left;PlatformHit.y = gameObject.bottom;
        overlapX = gameObject.xPos % maxTileSize;     
        //Measure the y overlap from far left side of the tile
        //and compensate for the object's height
        overlapY 
          = maxTileSize 
          - ((gameObject.yPos + gameObject.height) % maxTileSize);
        if(overlapY + gameObject.gravity_Vy >= overlapX)
        {
          if(gameObject.vy > 0
          && platformMap[gameObject.top][gameObject.left] 
          != platform)
          {
            //Collision on bottom
            gameObject.setY
              = (gameObject.mapRow * maxTileSize)
              + (maxTileSize - gameObject.height);
  		      gameObject.vy = -gameObject.vy * bounceY;
    		    gameObject.jumping = 0;
	  }
        }
        else
        {
          //Collision on left
          gameObject.setX 
            = gameObject.mapColumn * maxTileSize;
	  if(gameObject.vx < 0){gameObject.vx = -gameObject.vx * bounceX;}
        }
	  gameObject.setY = gameObject.yPos-offsetY;
	  gameObject.setX = gameObject.xPos+offsetX;
      }
      
      //If the object's bottom right corner is overlapping the tile
      //on its lower right side...
      if(platformMap[gameObject.bottom][gameObject.right] 
        != Constants.SKY)
      {
	PlatformHit.x = gameObject.right;PlatformHit.y = gameObject.bottom;
        //Measure the x and y overlap from the far right and bottom
        //side of the tile and compensate for the object's
        //height and width
        overlapX 
          = maxTileSize 
          - ((gameObject.xPos + gameObject.width) % maxTileSize);
        overlapY 
          = maxTileSize 
          - ((gameObject.yPos + gameObject.height) % maxTileSize);
        
        if(overlapY >= overlapX)
        {
          if(gameObject.vy > 0
          && platformMap[gameObject.top][gameObject.right] 
          != platform)
          {
            //Collision on bottom
            gameObject.setY 
              = (gameObject.mapRow * maxTileSize)
              + (maxTileSize - gameObject.height);
  		      gameObject.vy = -gameObject.vy * bounceY;
    		    gameObject.jumping = 0;
	  }
        }
        else
        {
          //Collision on right
          gameObject.setX 
            = (gameObject.mapColumn * maxTileSize)
            + ((maxTileSize - gameObject.width) - 1);
	  if(gameObject.vx > 0){ gameObject.vx = -gameObject.vx * bounceX;}
        }
	  gameObject.setX = gameObject.xPos-offsetX;
          gameObject.setY = gameObject.yPos-offsetY;
      }
      //If the object's top right corner is overlapping the tile
      //on its upper right side...
      if(platformMap[gameObject.top][gameObject.right] 
        != Constants.SKY)
      { 
	PlatformHit.x = gameObject.right;PlatformHit.y = gameObject.top;
        //Measure the x overlap from the far right side of the
        //tile and compensate for the object's width
        overlapX 
          = maxTileSize 
          - ((gameObject.xPos + gameObject.width) % maxTileSize);
        overlapY = gameObject.yPos % maxTileSize;
        
        if(overlapY >= overlapX)
        {
          if(gameObject.vy < 0
          && platformMap[gameObject.bottom][gameObject.right] 
          != platform)
          {
            gameObject.setY = (gameObject.mapRow * maxTileSize);
	    gameObject.vy = -gameObject.vy * bounceY;
	  }
        }
        else
        {
          //Collision on right
          gameObject.setX 
            = (gameObject.mapColumn * maxTileSize)
            + ((maxTileSize - gameObject.width) - 1);
	  if(gameObject.vx > 0){gameObject.vx = -gameObject.vx * bounceX;}
        }
	  gameObject.setY = gameObject.yPos+offsetY;
          gameObject.setX = gameObject.xPos-offsetX;
      }
      return PlatformHit;
    } 

  public function platformCollisionSquareModel
	(
	  gameObject:SquareModel, 
	  platformMap:Array<Array<Int>>, 
	  maxTileSize:Int,
	  platform:Int,
	  bounceY:Float = 0,
	  bounceX:Float = 0,
	  offsetY:Float = 0,
	  offsetX:Float = 0
	):Point
   { 
      var PlatformHit = new Point(-1,-1);
      //Variables needed to figure out by how much the object
      //is overlapping the tile on the x and y axis
      //The axis with the most overlap is the axis on which
      //the collision is occurring. This is an inverted SAT system
      var overlapX:Float;
      var overlapY:Float;
      //If the object's top left corner is overlapping the tile
      //on its upper left side...
      if(platformMap[gameObject.top][gameObject.left] != Constants.SKY)
      {
        //Figure out by how much the object's top left corner
        //point is overlapping the tile on both the x and y
        //axes. 
	PlatformHit.x = gameObject.left;PlatformHit.y = gameObject.top;
        overlapX = gameObject.xPos % maxTileSize;
        overlapY = gameObject.yPos % maxTileSize;
        if(overlapY >= overlapX)
        {
          if(gameObject.vy < 0
          && platformMap[gameObject.bottom][gameObject.left] 
          != platform)
          {
            //Collision on top side of the object
            //Position the object to the bottom 
            //edge of the platform tile
            //which it is overlapping and set its vy to zero
            gameObject.setY = (gameObject.mapRow * maxTileSize);
	    gameObject.vy = -gameObject.vy * bounceY;
	  }
  
        }
        else
        {
          //Collision on left side of the object
          //Position the object to the right 
          //edge of the platform tile and set its vx to zero
          gameObject.setX 
            = gameObject.mapColumn * maxTileSize;
          if(gameObject.vx < 0){gameObject.vx = -gameObject.vx * bounceX;}
        }
	  gameObject.setY = gameObject.yPos+offsetY;
          gameObject.setX = gameObject.xPos+offsetX;
      }
      
      //If the object's bottom left corner is overlapping the tile
      //on its lower left side...

      if(platformMap[gameObject.bottom][gameObject.left] != Constants.SKY)
      {
      PlatformHit.x = gameObject.left;PlatformHit.y = gameObject.bottom;
        overlapX = gameObject.xPos % maxTileSize;     
        //Measure the y overlap from far left side of the tile
        //and compensate for the object's height
        overlapY 
          = maxTileSize 
          - ((gameObject.yPos + gameObject.height) % maxTileSize);
        if(overlapY + gameObject.gravity_Vy >= overlapX)
        {
          if(gameObject.vy > 0
          && platformMap[gameObject.top][gameObject.left] 
          != platform)
          {
            //Collision on bottom
            gameObject.setY
              = (gameObject.mapRow * maxTileSize)
              + (maxTileSize - gameObject.height);
  		      gameObject.vy = -gameObject.vy * bounceY;
	  }
        }
        else
        {
          //Collision on left
          gameObject.setX 
            = gameObject.mapColumn * maxTileSize;
	  if(gameObject.vx < 0){gameObject.vx = -gameObject.vx * bounceX;}
        }
	  gameObject.setY = gameObject.yPos-offsetY;
	  gameObject.setX = gameObject.xPos+offsetX;
      }
      
      //If the object's bottom right corner is overlapping the tile
      //on its lower right side...
      if(platformMap[gameObject.bottom][gameObject.right] 
        != Constants.SKY)
      {
	PlatformHit.x = gameObject.right;PlatformHit.y = gameObject.bottom;
        //Measure the x and y overlap from the far right and bottom
        //side of the tile and compensate for the object's
        //height and width
        overlapX 
          = maxTileSize 
          - ((gameObject.xPos + gameObject.width) % maxTileSize);
        overlapY 
          = maxTileSize 
          - ((gameObject.yPos + gameObject.height) % maxTileSize);
        
        if(overlapY >= overlapX)
        {
          if(gameObject.vy > 0
          && platformMap[gameObject.top][gameObject.right] 
          != platform)
          {
            //Collision on bottom
            gameObject.setY 
              = (gameObject.mapRow * maxTileSize)
              + (maxTileSize - gameObject.height);
  		      gameObject.vy = -gameObject.vy * bounceY;
	  }
        }
        else
        {
          //Collision on right
          gameObject.setX 
            = (gameObject.mapColumn * maxTileSize)
            + ((maxTileSize - gameObject.width) - 1);
	  if(gameObject.vx > 0){ gameObject.vx = -gameObject.vx * bounceX;}
        }
	  gameObject.setX = gameObject.xPos-offsetX;
          gameObject.setY = gameObject.yPos-offsetY;
      }
      //If the object's top right corner is overlapping the tile
      //on its upper right side...
      if(platformMap[gameObject.top][gameObject.right] 
        != Constants.SKY)
      { 
	PlatformHit.x = gameObject.right;PlatformHit.y = gameObject.top;
        //Measure the x overlap from the far right side of the
        //tile and compensate for the object's width
        overlapX 
          = maxTileSize 
          - ((gameObject.xPos + gameObject.width) % maxTileSize);
        overlapY = gameObject.yPos % maxTileSize;
        
        if(overlapY >= overlapX)
        {
          if(gameObject.vy < 0
          && platformMap[gameObject.bottom][gameObject.right] 
          != platform)
          {
            gameObject.setY = (gameObject.mapRow * maxTileSize);
	    gameObject.vy = -gameObject.vy * bounceY;
	  }
        }
        else
        {
          //Collision on right
          gameObject.setX 
            = (gameObject.mapColumn * maxTileSize)
            + ((maxTileSize - gameObject.width) - 1);
	  if(gameObject.vx > 0){gameObject.vx = -gameObject.vx * bounceX;}
        }
	  gameObject.setY = gameObject.yPos+offsetY;
          gameObject.setX = gameObject.xPos-offsetX;
      }
      return PlatformHit;
    } 

 public function platformCollisionCircleModel
	(
	  gameObject:CircleModel, 
	  platformMap:Array<Array<Int>>, 
	  maxTileSize:Int,
	  platform:Int,
	  bounceY:Float = 0,
	  bounceX:Float = 0,
	  offsetY:Float = 0,
	  offsetX:Float = 0
	):Point
   { 
      var PlatformHit = new Point(-1,-1);
      //Variables needed to figure out by how much the object
      //is overlapping the tile on the x and y axis
      //The axis with the most overlap is the axis on which
      //the collision is occurring. This is an inverted SAT system
      var overlapX:Float;
      var overlapY:Float;
      //If the object's top left corner is overlapping the tile
      //on its upper left side...
      if(platformMap[gameObject.top][gameObject.left] != Constants.SKY)
      {
        //Figure out by how much the object's top left corner
        //point is overlapping the tile on both the x and y
        //axes. 
	PlatformHit.x = gameObject.left;PlatformHit.y = gameObject.top;
        overlapX = (gameObject.xPos-gameObject.width/2) % maxTileSize;
        overlapY = (gameObject.yPos-gameObject.height/2) % maxTileSize;
        if(overlapY >= overlapX)
        {
          if(gameObject.vy < 0
          && platformMap[gameObject.bottom][gameObject.left] 
          != platform)
          {
            //Collision on top side of the object
            //Position the object to the bottom 
            //edge of the platform tile
            //which it is overlapping and set its vy to zero
            gameObject.setY = (gameObject.mapRow * maxTileSize)+gameObject.height/2;
	    gameObject.vy = -gameObject.vy * bounceY;
	  }
  
        }
        else
        {
          //Collision on left side of the object
          //Position the object to the right 
          //edge of the platform tile and set its vx to zero
          gameObject.setX 
            = gameObject.mapColumn * maxTileSize+gameObject.width/2;
          if(gameObject.vx < 0){gameObject.vx = -gameObject.vx * bounceX;}
        }
	  gameObject.setY = gameObject.yPos+offsetY;
          gameObject.setX = gameObject.xPos+offsetX;
      }
      
      //If the object's bottom left corner is overlapping the tile
      //on its lower left side...

      if(platformMap[gameObject.bottom][gameObject.left] != Constants.SKY)
      {
      PlatformHit.x = gameObject.left;PlatformHit.y = gameObject.bottom;
        overlapX = (gameObject.xPos-(gameObject.width/2)) % maxTileSize;     
        //Measure the y overlap from far left side of the tile
        //and compensate for the object's height
        overlapY 
          = maxTileSize 
          - ((gameObject.yPos + gameObject.height/2) % maxTileSize);
        if(overlapY + gameObject.gravity_Vy >= overlapX)
        {
          if(gameObject.vy > 0
          && platformMap[gameObject.top][gameObject.left] 
          != platform)
          {
            //Collision on bottom
            gameObject.setY
              = (gameObject.mapRow * maxTileSize)
              + (maxTileSize - gameObject.height/2);
  		      gameObject.vy = -gameObject.vy * bounceY;
	  }
        }
        else
        {
          //Collision on left
          gameObject.setX 
            = gameObject.mapColumn * maxTileSize+gameObject.width/2;
	  if(gameObject.vx < 0){gameObject.vx = -gameObject.vx * bounceX;}
        }
	  gameObject.setY = gameObject.yPos-offsetY;
	  gameObject.setX = gameObject.xPos+offsetX;
      }
      
      //If the object's bottom right corner is overlapping the tile
      //on its lower right side...
      if(platformMap[gameObject.bottom][gameObject.right] 
        != Constants.SKY)
      {
	PlatformHit.x = gameObject.right;PlatformHit.y = gameObject.bottom;
        //Measure the x and y overlap from the far right and bottom
        //side of the tile and compensate for the object's
        //height and width
        overlapX 
          = maxTileSize 
          - ((gameObject.xPos + gameObject.width/2) % maxTileSize);
        overlapY 
          = maxTileSize 
          - ((gameObject.yPos + gameObject.height/2) % maxTileSize);
        
        if(overlapY >= overlapX)
        {
          if(gameObject.vy > 0
          && platformMap[gameObject.top][gameObject.right] 
          != platform)
          {
            //Collision on bottom
            gameObject.setY 
              = (gameObject.mapRow * maxTileSize)
              + (maxTileSize - gameObject.height/2);
  		      gameObject.vy = -gameObject.vy * bounceY;
	  }
        }
        else
        {
          //Collision on right
          gameObject.setX 
            = (gameObject.mapColumn * maxTileSize)
            + ((maxTileSize - gameObject.width/2));
	  if(gameObject.vx > 0){ gameObject.vx = -gameObject.vx * bounceX;}
        }
	  gameObject.setX = gameObject.xPos-offsetX;
          gameObject.setY = gameObject.yPos-offsetY;
      }
      //If the object's top right corner is overlapping the tile
      //on its upper right side...
      if(platformMap[gameObject.top][gameObject.right] 
        != Constants.SKY)
      { 
	PlatformHit.x = gameObject.right;PlatformHit.y = gameObject.top;
        //Measure the x overlap from the far right side of the
        //tile and compensate for the object's width
        overlapX 
          = maxTileSize 
          - ((gameObject.xPos + gameObject.width/2) % maxTileSize);
        overlapY = (gameObject.yPos - gameObject.height/2) % maxTileSize;
        
        if(overlapY >= overlapX)
        {
          if(gameObject.vy < 0
          && platformMap[gameObject.bottom][gameObject.right] 
          != platform)
          {
            gameObject.setY = (gameObject.mapRow * maxTileSize) + gameObject.height/2;
	    gameObject.vy = -gameObject.vy * bounceY;
	  }
        }
        else
        {
          //Collision on right
          gameObject.setX 
            = (gameObject.mapColumn * maxTileSize)
            + ((maxTileSize - gameObject.width/2));
	  if(gameObject.vx > 0){gameObject.vx = -gameObject.vx * bounceX;}
        }
	  gameObject.setY = gameObject.yPos+offsetY;
          gameObject.setX = gameObject.xPos-offsetX;
      }
      return PlatformHit;
    } 
  //roundTile collisions
  public function roundTileCollision
    (
      gameObject:AVerletModel, 
      roundTile_X:Int, 
      roundTile_Y:Int,
      tileRadius:Float
    ):Bool
  {
    var _v0:VectorModel = new VectorModel( gameObject.xPos, gameObject.yPos,roundTile_X,roundTile_Y);
    //Find the voronoi region
    var region:String = "";
    
    //Is the circle above the rectangle's top edge?
    if(roundTile_Y < gameObject.yPos - gameObject.height * 0.5)
    {
      //If it is, we need to check whether it's in the 
      //top left, top center or top right
      if(roundTile_X < gameObject.xPos - gameObject.width * 0.5)
      {
	region = "topLeft";
      }
      else if (roundTile_X > gameObject.xPos + gameObject.width * 0.5)
      {
	region = "topRight";
      }
      else
      {
	region = "topMiddle";
      }
    }
    //The circle isn't above the top edge, so it might be 
    //below the bottom edge
    else if (roundTile_Y > gameObject.yPos + gameObject.height * 0.5)
    {
      //If it is, we need to check whether it's in the 
      //bottom left, bottom center or bottom right
      if(roundTile_X < gameObject.xPos - gameObject.width * 0.5)
      {
	region = "bottomLeft";
      }
      else if (roundTile_X > gameObject.xPos + gameObject.width * 0.5)
      {
	region = "bottomRight";
      }
      else
      {
	region = "bottomMiddle";
      }
    }
    //The circle isn't above the top edge or below the bottom
    //edge so it must be on the left or right side
    else
    {
      if(roundTile_X < gameObject.xPos - gameObject.width * 0.5)
      {
	region = "leftMiddle";
      }
      else
      {
	region = "rightMiddle";
      }
    }
    var collision = false;
    //If the circle is in the topMiddle, 
    //bottomMiddle, leftMiddle or rightMiddle
    //perform the standard check for overlaps as you would
    //with a rectangle
    
      if(region == "topMiddle"
      || region == "bottomMiddle"
      || region == "leftMiddle"
      || region == "rightMiddle")
      {
      //Check whether the projection on 
      //the x axis (in this case the v0's vx) 
      //is less than the combined half widths
      if(Math.abs(_v0.vx) < tileRadius + gameObject.width * 0.5)
      {
	//A collision might be occurring! Check the other 
	//projection on the y axis (v0's vy)
	
	if(Math.abs(_v0.vy) < tileRadius + gameObject.height * 0.5)
	{
	  //A collision has occurred
	  
	  //Find out the size of the overlap on both the X and Y axis
	  var overlap_X:Float 
	    = tileRadius 
	    + gameObject.width * 0.5 
	    - Math.abs(_v0.vx);
	    
	  var overlap_Y:Float
	    = tileRadius
	    + gameObject.height * 0.5 
	    - Math.abs(_v0.vy);
	  
	  //The collision has occurred on the axis with the
	  //*smallest* amount of overlap. Let's figure out which
	  //axis that is
	  
	  if(overlap_X >=  overlap_Y)
	  {
	    collision = true;
	    //The collision is happening on the X axis
	    //But on which side? v0's vy can tell us 
	    if(_v0.vy > 0)
	    {
	      //collisionSide = "Top";
	    }
	    else
	    {
	      //collisionSide = "Bottom";
	    }                                  
	  }
	  else
	  {
	      
	    collision = true;
	    //The collision is happening on the Y axis
	    //But on which side? v0's vx can tell us 
	    if(_v0.vx > 0)
	    {
	      //CollisionSide = "Left";
	    }
	    else
	    {
	      //collisionSide = "Right";
	    }
	  }
	}
	else
	{
	  //"No collision";
	}
      }
      else
      {
	//"No collision";
      }
      
    }

     		//The circle isn't in danger of intersecting 
		//with any of the rectangle's planes,
		//so it has to be closer to one of the four corners
		//The checkCornerCollision method does the 
		//work of the collision detection
		//It takes four arguments:
		//1. The CircleModel object
		//2. The x position of the corner
		//3. The y position of the corner
		//4. The bounce multiplier which 
		//determines the amount of "bouncines"
		
		if(region == "topLeft")
		{
		  var cornerV0 = new VectorModel
		    (
		    roundTile_X,
		    roundTile_Y,
		    gameObject.xPos - gameObject.width * 0.5,
		    gameObject.yPos - gameObject.height * 0.5
		    );

		    if(cornerV0.m < tileRadius)
		    {
		     collision = true;
		    }
		}
		else if(region == "topRight")
		{
		  var cornerV0 = new VectorModel
		    (
		    roundTile_X,
		    roundTile_Y,
		    gameObject.xPos + gameObject.width * 0.5,
		    gameObject.yPos - gameObject.height * 0.5
		    );

		    if(cornerV0.m < tileRadius)
		    {
		      collision = true;
		    }
		}
		else if(region == "bottomLeft")
		{
		  var cornerV0 = new VectorModel
		    (
		    roundTile_X,
		    roundTile_Y,
		    gameObject.xPos - gameObject.width * 0.5,
		    gameObject.yPos +gameObject.height * 0.5
		    );

		    if(cornerV0.m < tileRadius)
		    {
		      collision = true;
		    }
		}
		else if(region == "bottomRight")
		{
		  var cornerV0 = new VectorModel
		    (
		    roundTile_X,
		    roundTile_Y,
		    gameObject.xPos+gameObject.width * 0.5,
		    gameObject.yPos +gameObject.height * 0.5
		    );

		    if(cornerV0.m < tileRadius)
		    {
		      collision = true;
		    }
		}
   return collision;
  }

}